/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "libzlang_datetime.h"

struct ZlangDirectProperty_datetime
{
	struct tm	tm ;
	struct timeval	tv ;
} ;

ZlangInvokeFunction ZlangInvokeFunction_datetime_GetNow;
int ZlangInvokeFunction_datetime_GetNow( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	
	gettimeofday( & (datetime_direct_prop->tv) , NULL );
	localtime_r( & (datetime_direct_prop->tv.tv_sec) , & (datetime_direct_prop->tm) );
	
	ReferObject( rt , out1 , obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_GetFromFormat;
int ZlangInvokeFunction_datetime_GetFromFormat( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in = NULL ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*format = NULL ;
	char					*datetime_str = NULL ;
	
	if( GetInputParameterCountInLocalObjectStack( rt ) != 2 )
		return ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED;
	
	in = GetInputParameterInLocalObjectStack(rt,1) ;
	GetDataPtr( rt , in , (void**) & format , NULL );
	in = GetInputParameterInLocalObjectStack(rt,2) ;
	GetDataPtr( rt , in , (void**) & datetime_str , NULL );
	
	strptime( datetime_str , format , & (datetime_direct_prop->tm) );
	
	ReferObject( rt , out1 , obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_SecondStamp;
int ZlangInvokeFunction_datetime_SecondStamp( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int64_t					secondstamp ;
	
	secondstamp = (int64_t)(datetime_direct_prop->tv.tv_sec) ;
	CallRuntimeFunction_long_SetLongValue( rt , out1 , secondstamp );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Year;
int ZlangInvokeFunction_datetime_Year( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					year ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	year = datetime_direct_prop->tm.tm_year + 1900 ;
	FromDataPtr( rt , out1 , & year , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Month;
int ZlangInvokeFunction_datetime_Month( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					month ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	month = datetime_direct_prop->tm.tm_mon + 1 ;
	FromDataPtr( rt , out1 , & month , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Day;
int ZlangInvokeFunction_datetime_Day( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					day ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	day = datetime_direct_prop->tm.tm_mday ;
	FromDataPtr( rt , out1 , & day , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Hour;
int ZlangInvokeFunction_datetime_Hour( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					hour ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	hour = datetime_direct_prop->tm.tm_hour ;
	FromDataPtr( rt , out1 , & hour , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Minute;
int ZlangInvokeFunction_datetime_Minute( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					minute ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	minute = datetime_direct_prop->tm.tm_min ;
	FromDataPtr( rt , out1 , & minute , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Second;
int ZlangInvokeFunction_datetime_Second( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					second ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	second = datetime_direct_prop->tm.tm_sec ;
	FromDataPtr( rt , out1 , & second , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_Microsecond;
int ZlangInvokeFunction_datetime_Microsecond( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					microsecond ;
	
	if( out1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	microsecond = datetime_direct_prop->tv.tv_usec ;
	FromDataPtr( rt , out1 , & microsecond , sizeof(int32_t) );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_FormatString_string;
int ZlangInvokeFunction_datetime_FormatString_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*obj_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*format = NULL ;
	char					buf[ 1024 ] ;
	int32_t					n ;
	
	int					nret = 0 ;
	
	GetDataPtr( rt , in1 , (void**) & format , NULL );
	
	memset( buf , 0x00 , sizeof(buf) );
	n = strftime( buf , sizeof(buf) , format , & (obj_direct_prop->tm) );
	
	nret = FromCharPtr( rt , out1 , buf , n ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "format\"%s\" -> formatting\"%s\"" , format , buf )
	if( nret )
		return nret;
	
	return 0;
}

/*                                       1    2    3    4    5    6    7    8    9    10   11   12 */
static int _sg_zlang_days_of_month[] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
#define IS_LEAP_YEAR(_year_)	( ( ((_year_)%4)==0&&((_year_)%4)!=0 ) || (_year_)%400==0 )

#define AMENDDATETIME_TYPE_SECOND	1
#define AMENDDATETIME_TYPE_MINUTE	2
#define AMENDDATETIME_TYPE_HOUR		3
#define AMENDDATETIME_TYPE_DAY		4
#define AMENDDATETIME_TYPE_MONTH	5
#define AMENDDATETIME_TYPE_YEAR		6

static void AmendDatetime( struct ZlangDirectProperty_datetime *datetime_direct_prop , int amend_datetime_type )
{
	int		end_day_of_month ;
	
	switch( amend_datetime_type )
	{
		case AMENDDATETIME_TYPE_SECOND:
			while( datetime_direct_prop->tm.tm_sec < 0 )
			{
				datetime_direct_prop->tm.tm_min--;
				datetime_direct_prop->tm.tm_sec += 60 ;
			}
			
			while( datetime_direct_prop->tm.tm_sec >= 60 )
			{
				datetime_direct_prop->tm.tm_min++;
				datetime_direct_prop->tm.tm_sec -= 60 ;
			}
			
		case AMENDDATETIME_TYPE_MINUTE:
			while( datetime_direct_prop->tm.tm_min < 0 )
			{
				datetime_direct_prop->tm.tm_hour--;
				datetime_direct_prop->tm.tm_min += 60 ;
			}
			
			while( datetime_direct_prop->tm.tm_min >= 60 )
			{
				datetime_direct_prop->tm.tm_hour++;
				datetime_direct_prop->tm.tm_min -= 60 ;
			}
			
		case AMENDDATETIME_TYPE_HOUR:
			while( datetime_direct_prop->tm.tm_hour < 0 )
			{
				datetime_direct_prop->tm.tm_mday--;
				datetime_direct_prop->tm.tm_hour += 24 ;
			}
			
			while( datetime_direct_prop->tm.tm_hour >= 24 )
			{
				datetime_direct_prop->tm.tm_mday++;
				datetime_direct_prop->tm.tm_hour -= 24 ;
			}
			
		case AMENDDATETIME_TYPE_DAY:
			while( datetime_direct_prop->tm.tm_mday < 1 )
			{
				datetime_direct_prop->tm.tm_mon--;
				end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
				if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
					end_day_of_month++;
				datetime_direct_prop->tm.tm_mday += end_day_of_month ;
			}
			
			end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
			if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
				end_day_of_month++;
			while( datetime_direct_prop->tm.tm_mday > end_day_of_month )
			{
				datetime_direct_prop->tm.tm_mon++;
				datetime_direct_prop->tm.tm_mday -= end_day_of_month ;
			}
			
		case AMENDDATETIME_TYPE_MONTH:
			while( datetime_direct_prop->tm.tm_mon < 0 )
			{
				datetime_direct_prop->tm.tm_year--;
				datetime_direct_prop->tm.tm_mon += 12 ;
			}
			
			while( datetime_direct_prop->tm.tm_mon >= 12 )
			{
				datetime_direct_prop->tm.tm_year++;
				datetime_direct_prop->tm.tm_mon -= 12 ;
			}
			
			end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
			if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
				end_day_of_month++;
			if( datetime_direct_prop->tm.tm_mday > end_day_of_month )
				datetime_direct_prop->tm.tm_mday = end_day_of_month ;
			
		case AMENDDATETIME_TYPE_YEAR:
			end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
			if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
				end_day_of_month++;
			if( datetime_direct_prop->tm.tm_mday > end_day_of_month )
				datetime_direct_prop->tm.tm_mday = end_day_of_month ;
			
	}
	
	return;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetYears_int_bool;
int ZlangInvokeFunction_datetime_OffsetYears_int_bool( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	int32_t					years ;
	unsigned char				IS_ATTRACTED_END_OF_MONTH ;
	int					end_day_of_month ;
	unsigned char				is_end_of_month = 0 ;
	
	if( in1 == NULL || in2 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & years );
	CallRuntimeFunction_bool_GetBoolValue( rt , in2 , & IS_ATTRACTED_END_OF_MONTH );
	
	if( IS_ATTRACTED_END_OF_MONTH == TRUE )
	{
		end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
		if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
			end_day_of_month++;
		
		if( datetime_direct_prop->tm.tm_mday == end_day_of_month )
			is_end_of_month = 1 ;
		else
			is_end_of_month = 0 ;
	}
	
	datetime_direct_prop->tm.tm_year += years ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_YEAR );
	
	if( IS_ATTRACTED_END_OF_MONTH == TRUE )
	{
		if( is_end_of_month )
		{
			end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
			if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
				end_day_of_month++;
			
			datetime_direct_prop->tm.tm_mday = end_day_of_month ;
		}
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetMonths_int_bool;
int ZlangInvokeFunction_datetime_OffsetMonths_int_bool( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	int32_t					months ;
	unsigned char				IS_ATTRACTED_END_OF_MONTH ;
	int					end_day_of_month ;
	unsigned char				is_end_of_month = 0 ;
	
	if( in1 == NULL || in2 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & months );
	CallRuntimeFunction_bool_GetBoolValue( rt , in2 , & IS_ATTRACTED_END_OF_MONTH );
	
	if( IS_ATTRACTED_END_OF_MONTH == TRUE )
	{
		end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
		if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
			end_day_of_month++;
		
		if( datetime_direct_prop->tm.tm_mday == end_day_of_month )
			is_end_of_month = 1 ;
		else
			is_end_of_month = 0 ;
	}
	
	datetime_direct_prop->tm.tm_mon += months ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_MONTH );
	
	if( IS_ATTRACTED_END_OF_MONTH == TRUE )
	{
		if( is_end_of_month )
		{
			end_day_of_month = _sg_zlang_days_of_month[datetime_direct_prop->tm.tm_mon] ;
			if( datetime_direct_prop->tm.tm_mon == 1 && IS_LEAP_YEAR(datetime_direct_prop->tm.tm_year+1900) )
				end_day_of_month++;
			
			datetime_direct_prop->tm.tm_mday = end_day_of_month ;
		}
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetDays;
int ZlangInvokeFunction_datetime_OffsetDays( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	int32_t					days ;
	
	if( in1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & days );
	
	datetime_direct_prop->tm.tm_mday += days ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_DAY );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetHours;
int ZlangInvokeFunction_datetime_OffsetHours( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	int32_t					hours ;
	
	if( in1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & hours );
	
	datetime_direct_prop->tm.tm_hour += hours ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_HOUR );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetMinutes;
int ZlangInvokeFunction_datetime_OffsetMinutes( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	int32_t					minutes ;
	
	if( in1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & minutes );
	
	datetime_direct_prop->tm.tm_min += minutes ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_MINUTE );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_datetime_OffsetSeconds;
int ZlangInvokeFunction_datetime_OffsetSeconds( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	int32_t					seconds ;
	
	if( in1 == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	CallRuntimeFunction_int_GetIntValue( rt , in1 , & seconds );
	
	datetime_direct_prop->tm.tm_sec += seconds ;
	
	AmendDatetime( datetime_direct_prop , AMENDDATETIME_TYPE_SECOND );
	
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_datetime;
void *ZlangCreateDirectProperty_datetime( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_prop = NULL ;
	
	datetime_prop = (struct ZlangDirectProperty_datetime *)ZLMALLOC( sizeof(struct ZlangDirectProperty_datetime) ) ;
	if( datetime_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( datetime_prop , 0x00 , sizeof(struct ZlangDirectProperty_datetime) );
	
	return datetime_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_datetime;
void ZlangDestroyDirectProperty_datetime( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	
	ZLFREE( datetime_direct_prop );
	
	return;
}

ZlangToStringFunction ZlangToString_datetime;
int ZlangToString_datetime( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **tostr_obj )
{
	struct ZlangDirectProperty_datetime	*datetime_direct_prop = GetObjectDirectProperty(obj) ;
	char					buf[ 10+1+8 + 1 ] = "" ;
	int32_t					str_len ;
	
	str_len = strftime( buf , sizeof(buf) , "%Y-%m-%d %H:%M:%S" , & (datetime_direct_prop->tm) ) ;
	CallRuntimeFunction_string_SetStringValue( rt , (*tostr_obj) , buf , str_len ) ;
	
	return 0;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_datetime;
void ZlangSummarizeDirectPropertySize_datetime( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_datetime) )
	return;
}

static struct ZlangDirectFunctions direct_funcs_datetime =
	{
		ZLANG_OBJECT_datetime , /* char *ancestor_name */
		
		ZlangCreateDirectProperty_datetime , /* ZlangCreateDirectPropertyFunction *create_entity_func */
		ZlangDestroyDirectProperty_datetime , /* ZlangDestroyDirectPropertyFunction *destroy_entity_func */
		
		NULL , /* ZlangFromCharPtrFunction *from_char_ptr_func */
		ZlangToString_datetime , /* ZlangToStringFunction *to_string_func */
		NULL , /* ZlangFromDataPtrFunction *from_data_ptr_func */
		NULL , /* ZlangGetDataPtrFunction *get_data_ptr_func */
		
		NULL , /* ZlangOperatorFunction *oper_PLUS_func */
		NULL , /* ZlangOperatorFunction *oper_MINUS_func */
		NULL , /* ZlangOperatorFunction *oper_MUL_func */
		NULL , /* ZlangOperatorFunction *oper_DIV_func */
		NULL , /* ZlangOperatorFunction *oper_MOD_func */
		
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NEGATIVE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NOT_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_BIT_REVERSE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_PLUS_PLUS_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_MINUS_MINUS_func */
		
		NULL , /* ZlangCompareFunction *comp_EGUAL_func */
		NULL , /* ZlangCompareFunction *comp_NOTEGUAL_func */
		NULL , /* ZlangCompareFunction *comp_LT_func */
		NULL , /* ZlangCompareFunction *comp_LE_func */
		NULL , /* ZlangCompareFunction *comp_GT_func */
		NULL , /* ZlangCompareFunction *comp_GE_func */
		
		NULL , /* ZlangLogicFunction *logic_AND_func */
		NULL , /* ZlangLogicFunction *logic_OR_func */
		
		NULL , /* ZlangLogicFunction *bit_AND_func */
		NULL , /* ZlangLogicFunction *bit_XOR_func */
		NULL , /* ZlangLogicFunction *bit_OR_func */
		NULL , /* ZlangLogicFunction *bit_MOVELEFT_func */
		NULL , /* ZlangLogicFunction *bit_MOVERIGHT_func */
		
		ZlangSummarizeDirectPropertySize_datetime , /* ZlangSummarizeDirectPropertySizeFunction *summarize_direct_prop_size_func */
	} ;

ZlangImportObjectFunction ZlangImportObject_datetime;
struct ZlangObject *ZlangImportObject_datetime( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangObject	*prop = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_datetime , & direct_funcs_datetime , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		return NULL;
	}
	
	/* bool datetime.ATTRACT_END_OF_MONTH */
	prop = AddPropertyInObject( rt , obj , QueryObjectByObjectName(rt,"bool") , "ATTRACT_END_OF_MONTH") ;
	if( prop == NULL )
		return NULL;
	CallRuntimeFunction_bool_SetBoolValue( rt , prop , TRUE );
	SetConstantObject( prop );
	
	/* bool datetime.NO_ATTRACT_END_OF_MONTH */
	prop = AddPropertyInObject( rt , obj , QueryObjectByObjectName(rt,"bool") , "NO_ATTRACT_END_OF_MONTH") ;
	if( prop == NULL )
		return NULL;
	CallRuntimeFunction_bool_SetBoolValue( rt , prop , FALSE );
	SetConstantObject( prop );
	
	/* datetime.GetNow() */
	func = AddFunctionAndParametersInObject( rt , obj , "GetNow" , "GetNow()" , ZlangInvokeFunction_datetime_GetNow , ZLANG_OBJECT_datetime , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.GetFromFormat() */
	func = AddFunctionAndParametersInObject( rt , obj , "GetFromFormat" , "GetFromFormat(string,string)" , ZlangInvokeFunction_datetime_GetFromFormat , ZLANG_OBJECT_datetime , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.SecondStamp() */
	func = AddFunctionAndParametersInObject( rt , obj , "SecondStamp" , "SecondStamp()" , ZlangInvokeFunction_datetime_SecondStamp , ZLANG_OBJECT_long , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Year() */
	func = AddFunctionAndParametersInObject( rt , obj , "Year" , "Year()" , ZlangInvokeFunction_datetime_Year , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Month() */
	func = AddFunctionAndParametersInObject( rt , obj , "Month" , "Month()" , ZlangInvokeFunction_datetime_Month , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Day() */
	func = AddFunctionAndParametersInObject( rt , obj , "Day" , "Day()" , ZlangInvokeFunction_datetime_Day , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Hour() */
	func = AddFunctionAndParametersInObject( rt , obj , "Hour" , "Hour()" , ZlangInvokeFunction_datetime_Hour , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Minute() */
	func = AddFunctionAndParametersInObject( rt , obj , "Minute" , "Minute()" , ZlangInvokeFunction_datetime_Minute , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Second() */
	func = AddFunctionAndParametersInObject( rt , obj , "Second" , "Second()" , ZlangInvokeFunction_datetime_Second , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.Microsecond() */
	func = AddFunctionAndParametersInObject( rt , obj , "Microsecond" , "Microsecond()" , ZlangInvokeFunction_datetime_Microsecond , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.FormatString(...) */
	func = AddFunctionAndParametersInObject( rt , obj , "FormatString" , "FormatString(string)" , ZlangInvokeFunction_datetime_FormatString_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetYears() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetYears" , "OffsetYears(int,bool)" , ZlangInvokeFunction_datetime_OffsetYears_int_bool , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , ZLANG_OBJECT_bool,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetMonths() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetMonths" , "OffsetMonths(int,bool)" , ZlangInvokeFunction_datetime_OffsetMonths_int_bool , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , ZLANG_OBJECT_bool,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetDays() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetDays" , "OffsetDays(int)" , ZlangInvokeFunction_datetime_OffsetDays , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetHours() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetHours" , "OffsetHours(int)" , ZlangInvokeFunction_datetime_OffsetHours , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetMinutes() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetMinutes" , "OffsetMinutes(int)" , ZlangInvokeFunction_datetime_OffsetMinutes , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* datetime.OffsetSeconds() */
	func = AddFunctionAndParametersInObject( rt , obj , "OffsetSeconds" , "OffsetSeconds(int)" , ZlangInvokeFunction_datetime_OffsetSeconds , ZLANG_OBJECT_void , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	return obj ;
}

